<template>
    <div class="app-container">
        <el-row :gutter="20">
            <el-col :span="4">
                <el-row :gutter="20">
                    <el-col>
                        <h4 class="office-label">组织机构</h4>
                    </el-col>
                    <!--机构树状图-->
                    <el-col>
                        <div class="head-container">
                            <el-input v-model="officeName" placeholder="请输入机构名称" clearable prefix-icon="Search"
                                style="margin-bottom: 20px" />
                        </div>
                        <div class="head-container">
                            <el-tree :data="officeTree" :props="{ label: 'label', children: 'children' }"
                                :expand-on-click-node="false" :filter-node-method="filterNode" ref="officeTreeRef"
                                node-key="id" highlight-current @node-click="handleNodeClick" />
                        </div>
                    </el-col>
                </el-row>
            </el-col>
            <el-col :span="20">
                <el-row :gutter="20">
                    <el-col>
                        <h4 class="office-label">用户列表</h4>
                    </el-col>
                    <!--用户列表-->
                    <el-col>
                        <div class="head-container">
                            <el-form ref="queryRef" :inline="true" label-width="68px">
                                <el-form-item label="所属医院" prop="company_id">
                                    <el-select v-model="queryParams.company_id" clearable @change="handleChange"
                                        placeholder="请选择所属医院">
                                        <el-option v-for="item in company" :key="item.id" :label="item.name"
                                            :value="item.id">
                                        </el-option>
                                    </el-select>
                                </el-form-item>
                                <el-form-item label="所属部门" prop="office_id">
                                    <el-select v-model="queryParams.office_id" clearable placeholder="请选择所属部门">
                                        <el-option v-for="item in office" :key="item.id" :label="item.name"
                                            :value="item.id">
                                        </el-option>
                                    </el-select>
                                </el-form-item>
                                <el-form-item label="登录名" prop="login_name">
                                    <el-input v-model="queryParams.login_name" placeholder="请输入登录名" clearable
                                        style="width: 240px" @keyup.enter="handleQuery" />
                                </el-form-item>
                                <el-form-item label="姓名" prop="name">
                                    <el-input v-model="queryParams.name" placeholder="请输入姓名" clearable style="width: 240px"
                                        @keyup.enter="handleQuery" />
                                </el-form-item>
                                <el-form-item>
                                    <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
                                    <el-button icon="Refresh" @click="resetQuery">重置</el-button>
                                </el-form-item>
                            </el-form>
                            <el-row :gutter="10" class="mb8">
                                <el-col :span="1.5">
                                    <el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
                                </el-col>
                                <el-col :span="1.5">
                                    <el-button type="success" plain icon="Edit" :disabled="hasEdit"
                                        @click="handleUpdate">修改</el-button>
                                </el-col>
                                <el-col :span="1.5">
                                    <el-button type="danger" plain icon="Delete" :disabled="hasDel"
                                        @click="handleDelete">删除</el-button>
                                </el-col>
                            </el-row>
                        </div>
                        <div class="head-container">
                            <el-table stripe ref="userTableRef" :data="userList" style="width: 100%"
                                @selection-change="handleSelectionChange" v-loading="loading">
                                <el-table-column type="selection" width="55" />
                                <el-table-column property="login_name" label="登录名" />
                                <el-table-column property="name" label="姓名" />
                                <el-table-column property="phone" label="电话" />
                                <el-table-column property="mobile" label="手机" />
                                <el-table-column property="company" label="所属医院" />
                                <el-table-column property="office" label="所属部门" />
                                <el-table-column label="状态" align="center" key="login_flag">
                                    <template #default="scope">
                                        <el-switch :disabled="scope.row.id == 1" v-model="scope.row.login_flag"
                                            active-value="0" inactive-value="1"
                                            @change="handleStatusChange(scope.row)"></el-switch>
                                    </template>
                                </el-table-column>
                                <el-table-column label="创建时间" align="center" prop="createTime" width="180px">
                                    <template #default="scope">
                                        <span>{{ parseTime(scope.row.createTime) }}</span>
                                    </template>
                                </el-table-column>
                                <el-table-column label="操作" align="center" width="150"
                                    class-name="small-padding fixed-width">
                                    <template #default="scope">
                                        <el-tooltip content="修改" placement="top" v-if="scope.row.id !== 1">
                                            <el-button link type="primary" icon="Edit"
                                                @click="handleUpdate(scope.row)"></el-button>
                                        </el-tooltip>
                                        <el-tooltip content="删除" placement="top" v-if="scope.row.id !== 1">
                                            <el-button link type="primary" icon="Delete"
                                                @click="handleDelete(scope.row)"></el-button>
                                        </el-tooltip>
                                        <el-tooltip content="重置密码" placement="top" v-if="scope.row.id !== 1">
                                            <el-button link type="primary" icon="Key"
                                                @click="handleResetPwd(scope.row)"></el-button>
                                        </el-tooltip>
                                    </template>
                                </el-table-column>
                            </el-table>
                            <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
                                v-model:limit="queryParams.pageSize" @pagination="bindUserList" />
                        </div>
                    </el-col>
                </el-row>
            </el-col>
        </el-row>
        <!-- 添加或修改用户配置对话框 -->
        <el-dialog :title="title" v-model="open" width="600px" @close="reset" append-to-body>
            <el-form :model="form" :rules="rules" ref="userListRef" label-width="80px">
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="所属医院" prop="company_id">
                            <el-select v-model="form.company_id" clearable @change="handleChangeForm" placeholder="请选择所属医院">
                                <el-option v-for="item in company" :key="item.id + ''" :label="item.name + ''"
                                    :value="item.id + ''">
                                </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="所属部门" prop="office_id">
                            <el-select v-model="form.office_id" clearable placeholder="请选择所属部门">
                                <el-option v-for="item in formOffice" :key="item.id + ''" :label="item.name + ''"
                                    :value="item.id + ''">
                                </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="工号" prop="no">
                            <el-input v-model="form.no" clearable placeholder="请输入工号" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="姓名" prop="name">
                            <el-input v-model="form.name" clearable placeholder="请输入姓名" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="登录名" prop="login_name">
                            <el-input v-model="form.login_name" clearable placeholder="请输入登录名" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="手机" prop="mobile">
                            <el-input v-model="form.mobile" clearable placeholder="请输入手机" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="密码" prop="password">
                            <el-input show-password type="password" v-model="form.password" clearable placeholder="请输入密码" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="确认密码" prop="rePassword">
                            <el-input show-password type="password" v-model="form.rePassword" clearable
                                placeholder="确认密码" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="邮箱" prop="email">
                            <el-input v-model="form.email" clearable placeholder="请输入邮箱" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="座机" prop="phone">
                            <el-input v-model="form.phone" clearable placeholder="请输入座机" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="用户类型" prop="user_type">
                            <el-select v-model="form.user_type" clearable placeholder="请选择用户类型">
                                <el-option v-for="item in user_sys_type" :key="item.value" :label="item.label"
                                    :value="item.value">
                                </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="是否启用" prop="login_flag">
                            <el-select :disabled="form.id == 1" v-model="form.login_flag" placeholder="是否启用">
                                <el-option v-for="item in yes_no" :key="item.value == 0 ? '1' : '0'" :label="item.label"
                                    :value="item.value == 0 ? '1' : '0'">
                                </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="角色" prop="roleIds">
                            <el-select v-model="form.roleIds" multiple placeholder="请选择">
                                <el-option v-for="item in roles" :key="item.id" :label="item.name" :value="item.id"
                                    :disabled="item.status == 1 || item.id == 10"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="使用人" prop="use_by">
                            <el-input v-model="form.use_by" clearable placeholder="推荐填写使用人手机号" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="头像" prop="photo">
                            <el-upload action="#" :show-file-list="false" :http-request="requestUpload"
                                :accept="'.jpg,.png,.jpeg'">
                                <img v-if="form.photo" :src="form.photo" class="avatar" />
                                <el-icon v-else class="avatar-uploader-icon">
                                    <Plus />
                                </el-icon>
                            </el-upload>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="备注" prop="remark">
                            <el-input type="textarea" v-model="form.remark" placeholder="请输入备注" />
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitForm">确 定</el-button>
                    <el-button @click="open = false">取 消</el-button>
                </div>
            </template>
        </el-dialog>
        <!-- 头像 -->
        <el-dialog title="裁剪头像" v-model="imgOpen" width="800px" append-to-body>
            <el-row>
                <el-col :xs="24" :md="12" :style="{ height: '350px' }">
                    <vue-cropper ref="cropper" :img="options.img" :info="true" :autoCrop="options.autoCrop"
                        :autoCropWidth="options.autoCropWidth" :autoCropHeight="options.autoCropHeight"
                        :fixedBox="options.fixedBox" :outputType="options.outputType" @realTime="realTime" v-if="true" />
                </el-col>
                <el-col :xs="24" :md="12" :style="{ height: '350px' }">
                    <div class="avatar-upload-preview">
                        <img :src="options.previews.url" :style="options.previews.img" />
                    </div>
                </el-col>
            </el-row>
            <br />
            <el-row>
                <el-col :lg="{ span: 1, offset: 2 }" :md="2">
                    <el-button icon="Plus" @click="changeScale(1)"></el-button>
                </el-col>
                <el-col :lg="{ span: 1, offset: 1 }" :md="2">
                    <el-button icon="Minus" @click="changeScale(-1)"></el-button>
                </el-col>
                <el-col :lg="{ span: 1, offset: 1 }" :md="2">
                    <el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
                </el-col>
                <el-col :lg="{ span: 1, offset: 1 }" :md="2">
                    <el-button icon="RefreshRight" @click="rotateRight()"></el-button>
                </el-col>
                <el-col :lg="{ span: 1, offset: 2 }" :md="2">
                </el-col>
                <el-col :lg="{ span: 2, offset: 6 }" :md="2">
                    <el-button type="primary" @click="handleCropper">确认</el-button>
                </el-col>
            </el-row>
        </el-dialog>
    </div>
</template>

<script setup name="User">
	import "vue-cropper/dist/index.css";
	import { VueCropper } from "vue-cropper";

	import { getOfficeTree, getCompany, getOffice } from '@/api/system/office';
	import { getUserList, changeLoginFlag, allRole, getUserInfo, updateUserInfo, addUserInfo, delUserInfo, resetPwd } from '@/api/system/user';
	const { proxy } = getCurrentInstance();

	/* 用户类型 是否启用 */
	const { user_sys_type, yes_no } = proxy.useDict("user_sys_type", "yes_no");
	/* 是否禁用修改按钮 */
	const hasEdit = ref(true);
	/* 是否禁用删除按钮 */
	const hasDel = ref(true);
	/* 树状图数据过滤词 */
	const officeName = ref('');
	/* 树状图数据 */
	const officeTree = ref([]);
	/* 用户列表数据 */
	const userList = ref([]);
	/* 所属医院数据 */
	const company = ref([]);
	/* 所属部门数据 */
	const office = ref([]);
	/* 表单部门数据 */
	const formOffice = ref([]);
	/* 总条数 */
	const total = ref(0);
	/* 用户修改添加对话框标题 */
	const title = ref('');
	/* 用户修改添加对话框显隐 */
	const open = ref(false);
	/* 表格加载动画 */
	const loading = ref(true);
	/* 选中列的id */
	const ids = ref([]);
	/* 选中用户的类型 */
	const userTypes = ref([]);
	/* 角色数据 */
	const roles = ref([]);
	/* 头像对话框 */
	const imgOpen = ref(false);

	/* 密码验证方法 */
	const checkPwd = (rule, value, callback) => {
		if (value != form.value.password) {
			callback(new Error());
		}
		callback();
	}

	/** 覆盖默认上传行为 */
	function requestUpload(option) {
		const sufixIndex = option.file.name.lastIndexOf(".");
		const sufix = option.file.name.substring(sufixIndex);
		if (sufix != ".jpg" && sufix != ".png" && sufix != ".jpeg") {
			proxy.$modal.msgError("文件类型错误");
			return;
		}
		const reader = new FileReader();
		reader.readAsDataURL(option.file);
		reader.onload = () => {
			options.img = reader.result;
		}
		imgOpen.value = true;
	}

	const data = reactive({
		queryParams: {
			pageNum: 1,
			pageSize: 10,
			login_name: undefined,
			name: undefined,
			company_id: undefined,
			office_id: undefined
		},
		form: {},
		rules: {
			company_id: [{ required: true, message: "所属医院不能为空", trigger: 'change' }],
			office_id: [{ required: true, message: "所属部门不能为空", trigger: 'change' }],
			no: [{ required: true, message: "工号不能为空", trigger: 'change' }],
			name: [{ required: true, message: "姓名不能为空", trigger: 'change' }],
			login_name: [
				{ required: true, message: "登录名不能为空", trigger: 'change' },
				{ min: 6, max: 20, message: "登录名长度必须介于 6 和 20 之间", trigger: "change" }
			],
			password: [
				{ required: true, message: "密码不能为空", trigger: 'change' },
				{ min: 6, max: 20, message: "密码长度必须介于 6 和 20 之间", trigger: "change" }
			],
			rePassword: [
				{ required: true, message: "确认密码不能为空", trigger: "change" },
				{ min: 6, max: 20, message: "密码长度必须介于 6 和 20 之间", trigger: "change" },
				{ validator: checkPwd, message: "两次密码必须一致", trigger: "change" },
				{ validator: checkPwd, message: "两次密码必须一致", trigger: "blur" }
			],
			user_type: [{ required: true, message: '用户类型不能为空', trigger: "change" }],
			roleIds: [{ required: true, message: "用户角色不能为空", trigger: "change" }],
			use_by: [{ required: true, message: "使用人不能为空", trigger: "change" }]
		}
	})

	const { queryParams, form, rules } = toRefs(data);

	//图片裁剪数据
	const options = reactive({
		img: form.value.photo, // 裁剪图片的地址
		autoCrop: true, // 是否默认生成截图框
		autoCropWidth: 200, // 默认生成截图框宽度
		autoCropHeight: 200, // 默认生成截图框高度
		fixedBox: true, // 固定截图框大小 不允许改变
		outputType: "png", // 默认生成截图为PNG格式
		previews: {} //预览数据
	});
	/* 处理裁剪 */
	function handleCropper() {
		proxy.$refs.cropper.getCropBlob(data => {
			const reader = new FileReader();
			reader.readAsDataURL(data)
			reader.onload = () => {
				form.value.photo = reader.result;
			}
		});
		imgOpen.value = false;
	}
	/** 向左旋转 */
	function rotateLeft() {
		proxy.$refs.cropper.rotateLeft();
	}
	/** 向右旋转 */
	function rotateRight() {
		proxy.$refs.cropper.rotateRight();
	}
	/** 图片缩放 */
	function changeScale(num) {
		num = num || 1;
		proxy.$refs.cropper.changeScale(num);
	}
	/** 实时预览 */
	function realTime(data) {
		options.previews = data;
	}
	/* 重置表单 */
	function reset() {
		form.value = {
			company_id: undefined,
			office_id: undefined,
			no: '',
			name: '',
			login_name: '',
			mobile: '',
			password: '',
			rePassword: '',
			email: '',
			phone: '',
			user_type: undefined,
			login_flag: '0',
			roleIds: [],
			photo: '',
			remark: ''
		};
		proxy.resetForm("userListRef");
		formOffice.value = [];
	}
	/* 重置条件 */
	function resetParams() {
		queryParams.value = {
			pageNum: 1,
			pageSize: 10,
			login_name: undefined,
			name: undefined,
			company_id: undefined,
			office_id: undefined
		}
		office.value = [];
		proxy.resetForm("queryRef");
	}
	/* 处理新增 */
	async function handleAdd() {
		reset();
		await allRole().then(response => {
			roles.value = response.data;
		});
		title.value = "新增用户"
		open.value = true;
	}
	/* 处理修改 */
	async function handleUpdate(row) {
		const userId = row.id || ids.value;
		if (userTypes.value) {
			if (userTypes.value.some(item => item == '0')) {
				proxy.$modal.msgError("不可修改超级管理员");
				return;
			}
		} else {
			if (row.user_type == '0') {
				proxy.$modal.msgError("不可修改超级管理员");
				return;
			}
		}
		reset();
		await allRole().then(response => {
			roles.value = response.data;
		});

		try {
			const response = await getUserInfo(userId);
			await handleChangeForm(response.data.company_id);
			form.value = response.data;
		} catch (e) {

		}

		title.value = "修改用户"
		open.value = true;
	}
	/* 处理删除 */
	function handleDelete(row) {
		const userIds = row.id || ids.value;
		if (userTypes.value) {
			if (userTypes.value.some(item => item == '0')) {
				proxy.$modal.msgError("不可删除超级管理员");
				return;
			}
		} else {
			if (row.user_type == '0') {
				proxy.$modal.msgError("不可删除超级管理员");
				return;
			}
		}
		proxy.$modal.confirm("确认要删除编号为“" + userIds + "”用户吗?").then(() => {
			return delUserInfo(userIds);
		}).then(response => {
			if (response.code == 200) {
				proxy.$modal.msgSuccess(response.msg);
			} else {
				proxy.$modal.msgError(response.msg);
			}
			handleQuery();
		})

	}
	/* 处理重置密码 */
	function handleResetPwd(row) {
		proxy.$modal.confirm("确认要重置“" + row.login_name + "”的密码吗?").then(() => {
			return resetPwd(row.id);
		}).then(response => {
			if (response.code == 200) {
				proxy.$modal.msgSuccess(response.msg);
			} else {
				proxy.$modal.msgError(response.msg);
			}
			handleQuery();
		})
	}
	/** 提交按钮 */
	function submitForm() {
		proxy.$refs["userListRef"].validate(valid => {
			console.log(valid)
			if (valid) {
				if (form.value.id) {
					updateUserInfo(form.value).then(response => {
						if (response.code == 200) {
							proxy.$modal.msgSuccess(response.msg);
						} else {
							proxy.$modal.msgError(response.msg);
						}
						handleQuery();
					});
				} else {
					addUserInfo(form.value).then(response => {
						if (response.code == 200) {
							proxy.$modal.msgSuccess(response.msg);
						} else {
							proxy.$modal.msgError(response.msg);
						}
						handleQuery();
					})
				}
			}
		});
	}
	/* 重置查询 */
	function resetQuery() {
		resetParams();
		handleQuery();
	}
	/** 搜索按钮操作 */
	async function handleQuery() {
		queryParams.value.pageNum = 1;
		await bindUserList();
	}
	/* 监听过滤词 */
	watch(officeName, val => {
		proxy.$refs["officeTreeRef"].filter(val);
	});
	/** 通过条件过滤节点  */
	const filterNode = (value, data) => {
		if (!value) return true;
		return data.label.indexOf(value) !== -1;
	};
	/** 处理树状图节点点击 */
	async function handleNodeClick(data, node) {
		if (node.level == 1) {
			resetParams();
			queryParams.value.company_id = data.id;
			await handleChange(data.id);
		} else {
			resetParams();
			// 最顶级节点
			let parent = node;
			while (parent.level > 1) {
				parent = parent.parent;
			}
			queryParams.value.company_id = parent.data.id;
			await handleChange(parent.data.id);
			queryParams.value.office_id = data.id;
		}
		await handleQuery();
	}
	/* 处理表格行选中 */
	function handleSelectionChange(selection) {
		ids.value = selection.map(item => item.id);
		userTypes.value = selection.map(item => item.user_type);
		hasEdit.value = selection.length != 1;
		hasDel.value = !selection.length;
	}
	/* 处理所属医院选中 */
	async function handleChange(value) {
		if (value) {
			await getOffice(value).then(response => {
				office.value = [];
				queryParams.value.office_id = undefined;
				office.value = response.data;
			});
		} else {
			office.value = [];
			queryParams.value.office_id = undefined;
		}
	}
	/* 处理所属医院选中 */
	async function handleChangeForm(value) {
		if (value) {
			await getOffice(value).then(response => {
				formOffice.value = [];
				form.value.office_id = undefined;
				formOffice.value = response.data;
			});
		} else {
			formOffice.value = [];
			form.value.office_id = undefined;
		}
	}
	/* 处理用户状态修改 */
	function handleStatusChange(row) {
		let text = row.login_flag === "0" ? "启用" : "停用";
		proxy.$modal.confirm("确认要" + text + "" + row.login_name + "用户吗?").then(() => {
			return changeLoginFlag(row.id, row.login_flag);
		}).then(() => {
			proxy.$modal.msgSuccess(text + "成功");
		}).catch(() => {
			row.login_flag = row.login_flag === "0" ? "1" : "0";
		})
	}

	/**
	 * 绑定机构树状图数据
	 */
	function bindOfficeTree() {
		getOfficeTree().then(response => {
			officeTree.value = response.data;
		});
	}

	/**
	 * 绑定所属医院数据
	 */
	function bindCompany() {
		getCompany().then(response => {
			company.value = response.data;
		})
	}

	/**
	 * 绑定用户列表
	 */
	async function bindUserList() {
		loading.value = true;
		await getUserList(queryParams.value).then(response => {
			userList.value = response.data;
			total.value = response.total;
			loading.value = false;
		});
	}

	bindOfficeTree();
	bindCompany();
	bindUserList();
</script>

<style scoped>
.app-container {
    padding-top: 0px;
}

.office-label {
    height: 40px;
    background: #f8fcff;
    line-height: 40px;
    padding-left: 10px;
    font-weight: bold;
    border: 0.5px solid #e2e2e2;
    border-radius: 5px;
}

.avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 150px;
    height: 150px;
    text-align: center;
}

.avatar {
    width: 150px;
    height: 150px;
    border-radius: 10px;
}

.user-info-head {
    position: relative;
    display: inline-block;
    height: 120px;
}

.user-info-head:hover:after {
    content: "+";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    color: #eee;
    background: rgba(0, 0, 0, 0.5);
    font-size: 24px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    cursor: pointer;
    line-height: 110px;
    border-radius: 50%;
}
</style>
